//Matthew Caraway
//Stephen Zapp
//CS314 Homework Assignment 1

import java.io.*;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.Set;

public class UI {

	private SystemManager sm;
	
	public UI(SystemManager sm) {
		this.sm = sm;
	}
	
	public void user_interface_main(){
		String choice="";
		boolean validChoice = false;

		while (validChoice == false){
			System.out.println("Start-up (Main) interface");
			System.out.println("1. Airline System");
			System.out.println("2. Cruise System");
			System.out.println("3. Exit");
			System.out.println("Enter one of the numbers above: ");


			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			try {
				choice = reader.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			} 
			if ( !(choice.matches("[1|2|3]")) ) {

				System.out.println ("Bad input. Try again. Only the given integers are valid");

			}
			else { validChoice = true;}

		}

		if (choice.equals("1")){ user_interface_main_airline(); }
		if (choice.equals("2")){	user_interface_main_cruise(); }
		if (choice.equals("3")){	System.exit(0); }

	}
	
	public void user_interface_main_airline(){
		String choice="";
		boolean validChoice = false;

		while (validChoice == false){
			System.out.println("Airline System interface");
			System.out.println("1. Admin Functions ");
			System.out.println("2. Find Available Seats ");
			System.out.println("3. Book Seat ");
			System.out.println("4. Return to Main");
			System.out.println("Enter one of the numbers above:");

			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			try {
				choice = reader.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			} 
			if ( !(choice.matches("[1|2|3|4]")) ) {


				System.out.println ("Bad input. Try again. Only the given integers are valid");

			}
			else { validChoice = true;}

		}

		if (choice.equals("1")){ admin_login(); }
		if (choice.equals("2")){	findSeats(); }
		if (choice.equals("3")){	bookSeat(); }
		if (choice.equals("4")){ user_interface_main(); }

	}
	
	public void user_interface_main_cruise(){
		String choice="";
		boolean validChoice = false;
		
		while (validChoice == false){
		System.out.println("Cruise System interface");
		System.out.println("1. Admin Functions ");
			user_interface_cruise_admin();
		System.out.println("2. Find Available Cabins ");
		System.out.println("3. Book Cabin ");
		System.out.println("4. Return to Main");
		System.out.println("Enter one of the numbers above:");
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			choice = reader.readLine();
		} catch (IOException e) {
            e.printStackTrace();
        } 
		if ( !(choice.matches("[1|2|3|4]")) ) {
				
			
			System.out.println ("Bad input. Try again. Only the given integers are valid");
			
		}
		else { validChoice = true;}
		
	}
		
		if (choice.equals("1")){ admin_login(); }
		if (choice.equals("2")){	findCabins(); }
		if (choice.equals("3")){	bookCabin(); }
		if (choice.equals("4")){ user_interface_main(); }
	}
	
	public void user_interface_airline_admin(){
		
		String choice="";
		boolean validChoice = false;
		
		while (validChoice == false){
		System.out.println("Airline Admin Functions Interface");
		System.out.println("1. Create an airport");
		System.out.println("2. Create an airline");
		System.out.println("3. Create a flight");
		System.out.println("4. Return to Airline Menu");
		System.out.println("Enter one of the numbers above: ");
		
		//choice = System.in.toString();
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			choice = reader.readLine();
		} catch (IOException e) {
            e.printStackTrace();
        } 
		if ( !(choice.matches("[1|2|3|4]")) ) {
				
			System.out.println ("Bad input. Try again. Only the given integers are valid");
			
		}
		else { validChoice = true;}
		
		}
		
		if (choice.equals("1")){ createAirport(); }
		if (choice.equals("2")){	createAirline(); }
		if (choice.equals("3")){	createFlight(); }
		if (choice.equals("4")){	user_interface_main_airline(); }
		

	}
	
	public void user_interface_cruise_admin(){
		String choice="";
		boolean validChoice = false;
		admin_login();
		
		while (validChoice == false){
			System.out.println("Cruise Admin Functions Interface");
			System.out.println("1. Create cruise");
			System.out.println("2. Create a port");
			System.out.println("3. Create a trip");
			System.out.println("4. Return to Cruise Menu");
			System.out.println("Enter one of the numbers above:");
			
//			choice = System.in.toString();
			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			try {
				choice = reader.readLine();
			} catch (IOException e) {
	            e.printStackTrace();
	        } 
			
			if ( !(choice.matches("[1|2|3|4]")) ) {
					
				
				System.out.println ("Bad input. Try again. Only the given integers are valid");
				
			}
			else { validChoice = true;}
			
		}
		
		if (choice.equals("1")){createCruise();}
		if (choice.equals("2")){createPort();}
		if (choice.equals("3")){createTrip();}
		if (choice.equals("4")){user_interface_main_cruise();}
		else {System.out.println("How did we get here?!");}	

	}
	
	public void admin_login(){
		
		String userName="", pwd="";
		boolean isCorrectLogin = false;
		boolean isCorrectPWD = false;
		
		while (isCorrectLogin == false){
			System.out.print("Please enter the Administrator's username: ");
			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			//userName = System.in.toString();
	        try {
	            userName = reader.readLine();
	        } catch (IOException e) {
	            e.printStackTrace();
	        } 
	        
			if (userName.equals("admin")){
				isCorrectLogin = true;
				
			}
			
			else {
				System.out.println("Invalid Administrator login.");
			}
			
		}
		
		
		while (isCorrectPWD == false){
			System.out.println("Please enter the password for this Administrator: ");

			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			//pwd = System.in.toString();
			try {
				pwd = reader.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			} 

			if(pwd.equals("admin123")){

				isCorrectPWD = true;
			}

			else{ System.out.println("Invalid password for the Administrator");}

		}
		
		user_interface_airline_admin();
			
	}
	
	public void createPort(){
	       
        String input = new String();
       
        System.out.println("Enter name of Port (must be exactly 3 characters long): ");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            input = reader.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
       
        if (sm.createPort(input) == null) {
            System.out.println("Invalid Port Name.");
            createPort();
        }
       
        user_interface_cruise_admin();
       
    }



    public void createCruise(){
       
        String input = new String();
       
        System.out.println("Enter name of cruiseline (must be 5 characters or less in length): ");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            input = reader.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
       
        if (sm.createCruiseline(input) == null) {
            System.out.println("Invalid Cruiseline Name.");
            createCruise();
        }  
    }
	
	public void createTrip(){
		
		
	}
	
	public void createAirport(){
		String input = new String();
		
		System.out.println("Enter name of airport (must be exactly 3 characters long): ");
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			input = reader.readLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		if (sm.createAirport(input) == null) {
			System.out.println("Invalid Airport Name.");
			createAirport();
		}
		
		user_interface_airline_admin();
		
	}
	
	public void createAirline(){
		String input = new String();
		
		System.out.println("Enter name of airline (must be 5 characters or less in length): ");
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			input = reader.readLine();
			input = input.toUpperCase();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		if (sm.createAirline(input) == null) {
			System.out.println("Invalid Airline Name.");
			createAirline();
		}
		
		user_interface_airline_admin();
	}
	
	public void createFlight(){
		String airline = "";
		String origAirport = "", destAirport = "";
		int year, month, day;
		String flightId = "";
		
		airline = assignAirline();
		
		System.out.println("Please choose an airport to depart from.");
		origAirport = assignAirport();
		System.out.println("Please choose a destination airport.");
		destAirport = assignAirport();
		
		if (origAirport.equals(destAirport)) {
			System.out.println("The source and destination airports cannot be the same. Starting over.");
			createFlight();
		}
	
		year = getYear();
		month = getMonth();
		day = getDay();
		
		flightId = assignFlightID();
		Flight flight = sm.createFlight(airline, origAirport, destAirport, year, month, day, flightId);
		if (flight == null) {
			System.out.println("Invalid flight ID. Try again.");
			createFlight();
		}
		boolean[] bools = {true, true, true, false};
		createSection(airline, flightId, bools);
		
		user_interface_airline_admin();
	}
	
	private String assignAirline() {
		String input = "";
		Hashtable<String, Airline> airlines = sm.getAirlines();
		Set<String> keys = airlines.keySet();
		
		System.out.println("Which airline will this flight be associated with? Here are your choices:");
		for (String key: keys) {
			System.out.println(key);
		}
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			input = reader.readLine();
			sm.findAirline(input);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ManagementException e) {
			assignAirline();
		}
		
		return input;
	}
	
	private String assignAirport() {
		String input = "";
		Hashtable<String, Airport> airports = sm.getAirports();
		Set<String> keys = airports.keySet();
		
		System.out.println("Here are your choices:");
		for (String key: keys) {
			System.out.println(key);
		}
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			input = reader.readLine();
			sm.findAirport(input);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ManagementException e) {
			assignAirport();
		}
		
		return input;
	}
	
	private int getYear() {
		int year = 0;
		System.out.println("In which year should this flight depart (must be 2014 or later)? ");
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			year = Integer.parseInt(reader.readLine());
		} catch (Exception e) {
			System.out.println("An error occurred parsing the year. Trying again.");
			getYear();
		}

		if (year < 2013){
			System.out.println("Year must be 2014 or later. Try again.");
			getYear();
		}
		return year;
	}
	
	private int getMonth() {
		int month = 0;
		System.out.println("In which month should this flight depart (must be an integer between 1 and 12 inclusive)? ");
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			month = Integer.parseInt(reader.readLine());
		} catch (Exception e) {
			System.out.println("An error occurred parsing the month. Trying again.");
			getYear();
		} 

		if (month < 1 || month > 12){
			System.out.println("Month must be between 1 and 12. Try again.");
			getMonth();
		}
		return month;
	}
	
	private int getDay() {
		int day = 0;
		System.out.println("On which day should this flight depart (must be an integer)? ");
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			day = Integer.parseInt(reader.readLine());
		} catch (Exception e) {
			System.out.println("An error occurred parsing the day. Trying again.");
			getDay();
		}

		return day;
	}
	
	public String assignFlightID() {
		String input = "";
		
		System.out.println("Please enter a unique flight ID. It should contain only alphanumeric characters. ");
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			input = reader.readLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		if (input.matches("^.*[^a-zA-Z0-9].*$") || input.length() < 3 || input.length() > 6) {
			System.out.println("Flight ID must be a string of 3 to 6 alphanumeric characters, try again.");
			assignFlightID();
		}
		return input;
	}
	
	private void createSection(String airline, String flightId, boolean[] bools) {
		
		int input=-1;
		
		System.out.println("Here are the possible seating sections:");
		System.out.println("Please enter the corresponding number");

		if (bools[0])
			System.out.println("1. First Class");
		if (bools[1])
			System.out.println("2. Business");
		if (bools[2])
			System.out.println("3. Economy");
		if (bools[3])
			System.out.println("4. Done");				


		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			input = Integer.parseInt(reader.readLine());
		} catch (IOException e) {
			e.printStackTrace();
		} 
		if (input < 0 || input > 4){
			System.out.println("You have entered an invalid section. Please try again.");
			createSection(airline, flightId, bools);
		}


		if (input == 4 && bools[3]){return;}
		else if (input != 4) {
			bools[input-1] = false;
			bools[3] = true;
			createSeatsForSection(airline, flightId, input-1);
			createSection(airline, flightId, bools);
		}
		//If 4 is entered before it is a valid value
		else{		

			createSection (airline, flightId, bools);
		}
	}
	
	private void createSeatsForSection(String airline, String flightId, int seatClass){
		int rows = 0;
		int cols = 0;
		
		System.out.println("How many rows would you like in this section (1-100)? ");
		
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			
			rows = Integer.parseInt(reader.readLine());
			if (rows < 1 || rows > 100){
				System.out.println("You have entered an invalid number of rows. Please try again.");
				createSeatsForSection(airline, flightId, seatClass);
			}
			
		}catch (Exception e){
			
			
		}
		
		System.out.println("How many columns would you like in this section (1-10)? ");
		
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			
			cols = Integer.parseInt(reader.readLine());
			if (cols < 1 || cols > 10){
				System.out.println("You have entered an invalid number of columns. Please try again.");
				createSeatsForSection(airline, flightId, seatClass);
			}
			
		}catch (Exception e){
			
			
		}
		
		if (seatClass == 0) {
			
		} else if (seatClass == 1) {
			
		}
		
	}
	
	public void bookSeat(){
		String airlineInput = "", flightInput = "", sectionInput = "";
		Airline airline = null;
		Flight flight = null;
		FlightSection sec = null;
		LinkedList<FlightSection> sections = null; 
		Set<String> airlines = sm.getAirlines().keySet();
		Set<String> flights = null;
		
		System.out.println("Which airline would you like to book a seat with? Here are your choices:");
		for (String al: airlines) {
			System.out.println(al);
		}
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try {
			airlineInput = reader.readLine();
			airline = sm.findAirline(airlineInput);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ManagementException e) {
			System.out.println("Invalid airline. Try again.");
			bookSeat();
		}
		
		//Now that the user has chosen an airline
		//We display a list of all flights for that airline
		System.out.println("Which flight would you like to book a seat on? Here are your choices:");
		
		flights = airline.getFlights().keySet();
		for (String key: flights) {
			System.out.println(airline.getFlights().get(key).usefulToString());
		}
		
		System.out.println("Please enter the ID of the flight: ");
		
		try {
			flightInput = reader.readLine();
			flight = airline.findFlight(flightInput);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (NullPointerException e) {
			System.out.println("Invalid flight. Try again.");
			bookSeat();
		}
		
		System.out.println("Here are the available sections on this flight:");
		sections = flight.getFlightSections();
		for (int i = 0; i < sections.size(); i++) {
			FlightSection currSection = sections.get(i);
			if (currSection.hasAvailableSeat()) {
				System.out.println(currSection.getType().toString());
			}
		}
		
		System.out.println("In which section would you like to sit? ");
		
		try {
			sectionInput = reader.readLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		int i;
		int [] seatLocation;
		for (i = 0; i < sections.size(); i++) {
			if (sections.get(i).getType().toString().equalsIgnoreCase(sectionInput)) {
				seatLocation = sections.get(i).bookNextAvailableSeat();
				sm.bookSeat(airlineInput, flight.getId(), sections.get(i).getType(), seatLocation[0], seatLocation[1]);
				break;
			}
		}
		
		if (i == sections.size()) {
			System.out.println("Invalid Section. Try again.");
			bookSeat();
		}
		
		
		
	}
	
	public void findSeats(){
		
		sm.displaySystemDetails();
		user_interface_main_airline();
	
	}
	
	public void findCabins(){
		
		user_interface_main_cruise();
	
	}
	
	public void bookCabin(){
		
		
		user_interface_main_cruise();
		
	}

}//end class
